<?php

namespace App\Http\Controllers;

use App\Exports\SearchStage\PcBookTitleExport29;
use App\Exports\SearchStage\PcBookCatalogExport29;
use App\Exports\SearchStage\PcBookTitleExport8;
use App\Exports\SearchStage\PcBookCatalogExport8;
use App\Exports\SearchStage\PcFullIndexExport;
use App\Exports\SearchStage\UpFullIndexExport;
use App\Exports\SearchStage\UpBookTitleExport29;
use App\Exports\SearchStage\UpBookTitleExport8;
use App\Exports\SearchStage\UpBookCatalogExport29;
use App\Exports\SearchStage\UpBookCatalogExport8;
use App\Models\ApprovalBorrow;
use App\Models\PartCompany;
use App\Models\Project;
use App\Models\ProjectClassify;
use App\Models\SearchHistory;
use App\Services\ApprovalService;
use App\Services\CommonService;
use App\Services\DownloadJobService;
use App\Services\ProjectSearchService;
use App\Services\ProjectService;
use App\Services\SearchStageService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/**
 * 【检索阶段】
 */
class SearchStageController extends Controller
{
    public $searchStageService;
    public $projectService;

    public function __construct(SearchStageService $searchStageService, ProjectService $projectService)
    {
        parent::__construct();
        $this->searchStageService = $searchStageService;
        $this->projectService     = $projectService;
    }

    /**
     * 按照参见单位 导出案卷目录
     *
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/3/2 13:59
     */
    public function partCompanyExportBookTitles(): JsonResponse
    {
        try {
            $projectId        = request()->input('project_id');
            $partCompanyId    = request()->input('part_company_id');
            $selectRows       = request()->input('selectRows');
            $selectRowsFormat = []; //格式化选择的案卷参数
            foreach ($selectRows as $selectRow) {
                $selectRowArr                                             = json_decode($selectRow, true);
                $selectRowsFormat[$selectRowArr['project_classify_id']][] = $selectRowArr['id'];
            }
            $serialNos       = date('His');
            $partCompanyName = PartCompany::query()->where('id', $partCompanyId)->value('title');
            $fileName        = get_valid_path("$partCompanyName . '_案卷目录_' . $serialNos .xlsx");
            $filePath        = "public/excels/$fileName";
            $combinationId   = Project::query()->where('id', $projectId)->value('combination_id');
            switch ($combinationId) {
                case 1: //29号文格式
                    (new PcBookTitleExport29($partCompanyId, $selectRowsFormat))->store($filePath);
                    break;
                default://8号文
                    (new PcBookTitleExport8($partCompanyId, $selectRowsFormat))->store($filePath);
                    break;
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
        $filePath    = str_replace('public', 'storage', $filePath);
        $downloadUrl = config('site.domain') . $filePath;
        $fileInfo    = pathinfo($downloadUrl);
        $data        = [
            'basename'     => $fileInfo['basename'],
            'download_url' => $downloadUrl
        ];
        CommonService::addProjectActionLog('导出案卷目录', 0, $partCompanyId, 0);

        return $this->success($data);
    }

    /**
     * 按照参见单位 导出卷内目录
     *
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/3/2 13:59
     */
    public function partCompanyExportBookCatalogs(): JsonResponse
    {
        try {
            $projectId        = request()->input('project_id');
            $partCompanyId    = request()->input('part_company_id');
            $selectRows       = request()->input('selectRows');
            $selectRowsFormat = []; //格式化选择的案卷参数
            foreach ($selectRows as $selectRow) {
                $selectRowArr                                             = json_decode($selectRow, true);
                $selectRowsFormat[$selectRowArr['project_classify_id']][] = $selectRowArr['id'];
            }
            $serialNos       = date('His');
            $partCompanyName = PartCompany::query()->where('id', $partCompanyId)->value('title');
            $filePath        = 'public/excels/' . $partCompanyName . '_卷内目录_' . $serialNos . '.xlsx';
            $combinationId   = Project::query()->where('id', $projectId)->value('combination_id');
            switch ($combinationId) {
                case 1: //29号文格式
                    (new PcBookCatalogExport29($partCompanyId, $selectRowsFormat))->store($filePath);
                    break;
                default://8号文
                    (new PcBookCatalogExport8($partCompanyId, $selectRowsFormat))->store($filePath);
                    break;
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
        $filePath    = str_replace('public', 'storage', $filePath);
        $downloadUrl = config('site.domain') . $filePath;
        $fileInfo    = pathinfo($downloadUrl);
        $data        = [
            'basename'     => $fileInfo['basename'],
            'download_url' => $downloadUrl
        ];
        CommonService::addProjectActionLog('检索阶段参建单位导出卷内目录', 0, $partCompanyId, 0);

        return $this->success($data);
    }

    /**
     * 按照参见单位 获取全引目录
     *
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/3/4 16:39
     */
    public function partCompanyExportFullIndexes(): JsonResponse
    {
        $projectId        = request()->input('project_id');
        $partCompanyId    = request()->input('part_company_id');
        $selectRows       = request()->input('selectRows');
        $selectRowsFormat = []; //格式化选择的案卷参数
        foreach ($selectRows as $selectRow) {
            $selectRowArr = json_decode($selectRow, true);
            $selectRowsFormat[$selectRowArr['project_classify_id']][] = $selectRowArr['id'];
        }
        $project         = Project::query()->where('id', $projectId)->first();
        $partCompanyName = PartCompany::query()->where('id', $partCompanyId)->value('title');
        $serialNos       = date('His');
        $filePath        = 'public/excels/' . $project->title.'_'.$partCompanyName . '_全引目录_' . $serialNos . '.xlsx';
        $combinationId   = $project->combination_id;
        switch ($combinationId) {
            case 1: //29号文格式
                (new PcFullIndexExport($partCompanyId, $partCompanyName, $selectRowsFormat))->store($filePath);
                break;
            default://8号文
                (new PcFullIndexExport($partCompanyId, $partCompanyName, $selectRowsFormat))->store($filePath);
                break;
        }
        $filePath    = str_replace('public', 'storage', $filePath);
        $downloadUrl = config('site.domain') . $filePath;
        $fileInfo    = pathinfo($downloadUrl);
        $data        = [
            'basename'     => $fileInfo['basename'],
            'download_url' => $downloadUrl
        ];
        CommonService::addProjectActionLog('检索阶段参建单位导出全引目录', 0, $partCompanyId, 0);

        return $this->success($data);
    }

    /**
     * 按照参见单位 检索
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/2/22 11:19
     */
    public function getPartCompanyBookTitles(Request $request): JsonResponse
    {
        $partCompanyId   = $request->input('part_company_id');
        $unitProjectName = $request->input('unit_project_name');
        $archivesNo      = $request->input('archives_no');
        $titleKeyword    = $request->input('title_keyword');
        $perPage         = $request->input('per_page', config('site.limit'));

        $data = $this->searchStageService->getPartCompanyBookTitles($partCompanyId, $unitProjectName, $titleKeyword, $archivesNo, $perPage, 0);

        return $this->success($data);
    }

    /**
     * 按照单位工程  当前用户相关的项目分类，并不是整个项目分类下的内容都能看
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/2/22 11:17
     */
    public function getProjectClassify(Request $request): JsonResponse
    {
        $projectId = $request->input('project_id');

        $list = $this->searchStageService->getProjectClassify($projectId);

        return $this->success($list);
    }

    /**
     * 按照单位工程 检索案卷目录
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/2/22 11:18
     */
    public function getProjectClassifyBookTitles(Request $request): JsonResponse
    {
        $projectId         = $request->input('project_id');
        $projectClassifyId = $request->input('project_classify_id');
        $isHaveChildren    = $request->input('is_have_children'); //是否有下级
        $partCompanyName   = $request->input('part_company_name');
        $titleKeyword      = $request->input('title_keyword');
        $archivesNo        = $request->input('archives_no');
        $perPage           = $request->input('per_page', config('site.limit'));
        $status            = 0;

        $needTables = $this->getNeedTables($projectId, $projectClassifyId, $isHaveChildren, $partCompanyName);

        $list = $this->searchStageService->getUnionBookTitleList2($projectId, $needTables, $perPage, $titleKeyword, $archivesNo, $status);

        return $this->success($list);
    }

    /**
     * 获取满足条件的数据表
     *
     * @param $projectId
     * @param $projectClassifyId
     * @param $isHaveChildren
     * @param $partCompanyName
     * @return array
     * @author: lxk
     * @date: 2025-01-10 13:02
     */
    public function getNeedTables($projectId, $projectClassifyId, $isHaveChildren, $partCompanyName) : array
    {
        $tables = [];
        if ($partCompanyName) { //如果进行了参建单位名称搜索
            $partCompanyIds = PartCompany::query()->where('project_id', $projectId)->where('title', 'like', "%{$partCompanyName}%")->pluck('id');
            $partCompanyIds = $partCompanyIds->isNotEmpty() ? $partCompanyIds->toArray() : [];
        } else {
            $partCompanyIds = ApprovalService::getPartCompanyIds($projectId);
        }
        if ($isHaveChildren) { //如果有下级
            $redisKey = "stChildrenBts:{$projectId}:{$projectClassifyId}";
            $tables   = redis()->smembers($redisKey);
        } else {
            foreach ($partCompanyIds as $partCompanyId) {
                $tables[] = "book_titles_{$partCompanyId}_{$projectClassifyId}";
            }
        }
        $tables = array_filter($tables, function ($table) use ($partCompanyIds) {
            $tableParam = CommonService::getTableParams($table);
            if (in_array($tableParam['id1'], $partCompanyIds)) {
                return $table;
            }
            return '';
        });
        $needTables = [];
        foreach ($tables as $table) {
            if (Schema::hasTable($table) && DB::table($table)->whereNull('deleted_at')->count()) {
                $needTables[] = $table;
            }
        }

        return $needTables;
    }

    /**
     * 按照单位工程 导出案卷目录
     *
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/3/2 13:59
     */
    public function projectClassifyExportBookTitles(): JsonResponse
    {
        try {
            $projectId         = request()->input('project_id');
            $projectClassifyId = request()->input('project_classify_id');
            $isHaveChildren    = request()->input('is_have_children');
            $selectRows        = request()->input('selectRows', []);

            $project       = Project::query()->where('id', $projectId)->first();
            $dirName       = $project->title. '_' . ProjectClassify::query()->where('id', $projectClassifyId)->value('title') . '_案卷目录_' . date('His');
            $tableAndIds   = $this->getTableIds($projectId, $projectClassifyId, $isHaveChildren, $selectRows);
            $combinationId = $project->combination_id;
            foreach ($tableAndIds as $table => $ids) {
                $tableParam    = CommonService::getTableParams($table);
                $proClassId2   = $tableParam['id2'];
                $proClassTitle = ProjectClassify::query()->where('id', $proClassId2)->value('title') . '_id=' . $proClassId2;
                $proClassTitle = get_valid_path($proClassTitle); // 把路径中可能出现的非法字符去掉
                $filePath      = 'public/excels/' . $dirName . '/案卷目录_' . $proClassTitle . '.xlsx';
                switch ($combinationId) {
                    case 1: //29号文格式
                        (new UpBookTitleExport29($table, $ids))->store($filePath);
                        break;
                    default://8号文
                        (new UpBookTitleExport8($table, $ids))->store($filePath);
                        break;
                }
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
        $dirStorage  = "storage/excels/$dirName";
        $downloadUrl = (new DownloadJobService())->mergeExcel($dirStorage);
        $fileInfo    = pathinfo($downloadUrl);
        $data        = [
            'basename'     => $fileInfo['basename'],
            'download_url' => $downloadUrl
        ];
        CommonService::addActionLog('检索阶段按照单位工程导出案卷目录');

        return $this->success($data);
    }

    /**
     * 获取涉及到的数据表和id
     *
     * @param $projectId
     * @param $projectClassifyId
     * @param $isHaveChildren
     * @param $selectRows
     * @return array
     * @author: lxk
     * @date: 2025-01-08 17:37
     */
    public function getTableIds($projectId, $projectClassifyId, $isHaveChildren, $selectRows): array
    {
        $tableAndIds = [];
        if ($selectRows) { //如果有勾选，优先使用
            foreach ($selectRows as $selectRow) {
                $selectRowArr = json_decode($selectRow, true);
                $key          = $selectRowArr['part_company_id'] . '_' . $selectRowArr['project_classify_id'];
                $tableAndIds["book_titles_$key"][] = $selectRowArr['id'];
            }
        } else {
            if ($isHaveChildren) {
                $redisKey = "stChildrenBts:{$projectId}:{$projectClassifyId}";
                $tables   = redis()->smembers($redisKey);
                foreach ($tables as $table) {
                    if (Schema::hasTable($table) && DB::table($table)->whereNull('deleted_at')->count()) {
                        $tableAndIds[$table][] = 0; //被认为是全部案卷
                    }
                }
            } else {
                $partCompanyIds = ApprovalService::getPartCompanyIds($projectId);
                foreach ($partCompanyIds as $partCompanyId) {
                    $table = "book_titles_{$partCompanyId}_{$projectClassifyId}";
                    if (Schema::hasTable($table) && DB::table($table)->whereNull('deleted_at')->count()) {
                        $tableAndIds[$table][] = 0; //被认为是全部案卷
                    }
                }
            }
        }
        return $tableAndIds;
    }


    /**
     * 按照单位工程 导出卷内目录
     *
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/3/2 13:59
     */
    public function projectClassifyExportBookCatalogs(): JsonResponse
    {
        try {
            $projectId         = request()->input('project_id');
            $projectClassifyId = request()->input('project_classify_id');
            $partCompanyId     = 0;
            $bookTitleIds      = request()->input('ids');
            $bookTitleIds      = to_array($bookTitleIds);
            if (empty($bookTitleIds)) {
                $partCompanyIds = ApprovalService::getPartCompanyIds($projectId);
                foreach ($partCompanyIds as $id) {
                    $table = "book_titles_{$id}_{$projectClassifyId}";
                    if (Schema::hasTable($table) && DB::table($table)->whereNull('deleted_at')->count()) {
                        $partCompanyId = $id;
                        $bookTitleIds  = CommonService::getBookTitleInstance($partCompanyId, $projectClassifyId)->pluck('id')->toArray();
                        break;
                    }
                }
            }
            $eachChunk = 10;
            $project   = Project::query()->where('id', $projectId)->first();
            $arrChunks = array_chunk($bookTitleIds, $eachChunk); //选中的book_title_ids分割，每部分几个元素
            $dirName   = $project->title. '_' . ProjectClassify::query()->where('id', $projectClassifyId)->value('title') . '_卷内目录_' . date('His');
            $combinationId = $project->combination_id;
            $bookTitleInstance = CommonService::getBookTitleInstance($partCompanyId, $projectClassifyId);
            foreach ($arrChunks as $ids) {
                $serialNos = DownloadJobService::getChildSerialNos($bookTitleInstance, $ids);
                $dirName   = get_valid_path($dirName);
                $filePath  = 'public/excels/' . $dirName .'/'. $serialNos. '_卷内目录_' . date('His') . '.xlsx';
                switch ($combinationId) {
                    case 1: //29号文格式
                        (new UpBookCatalogExport29($partCompanyId, $projectClassifyId, $ids, $serialNos))->store($filePath);
                        break;
                    default: //8号文
                        (new UpBookCatalogExport8($partCompanyId, $projectClassifyId, $ids, $serialNos))->store($filePath);
                        break;
                }
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
        $dirStorage  = "storage/excels/$dirName";
        $downloadUrl = (new DownloadJobService())->mergeExcel($dirStorage);
        $fileInfo    = pathinfo($downloadUrl);
        $data        = [
            'basename'     => $fileInfo['basename'],
            'download_url' => $downloadUrl
        ];
        CommonService::addActionLog('检索阶段按照单位工程导出卷内目录');

        return $this->success($data);
    }


    /**
     * 按照参见单位 获取全引目录
     *
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/3/4 16:39
     */
    public function projectClassifyExportFullIndexes(): JsonResponse
    {
        try {
            $projectId         = request()->input('project_id');
            $projectClassifyId = request()->input('project_classify_id');
            $partCompanyId     = 0;
            $bookTitleIds      = request()->input('ids');
            $bookTitleIds      = to_array($bookTitleIds);
            if (empty($bookTitleIds)) {
                $partCompanyIds = ApprovalService::getPartCompanyIds($projectId);
                foreach ($partCompanyIds as $id) {
                    $table = "book_titles_{$id}_{$projectClassifyId}";
                    if (Schema::hasTable($table) && DB::table($table)->whereNull('deleted_at')->count()) {
                        $partCompanyId = $id;
                        $bookTitleIds  = CommonService::getBookTitleInstance($partCompanyId, $projectClassifyId)->pluck('id')->toArray();
                        break;
                    }
                }
            }
            $eachChunk = 10;
            $project   = Project::query()->where('id', $projectId)->first();
            $arrChunks = array_chunk($bookTitleIds, $eachChunk); //选中的book_title_ids分割，每部分几个元素
            $dirName   = $project->title. '_' . ProjectClassify::query()->where('id', $projectClassifyId)->value('title') . '_全引目录_' . date('His');
            $combinationId = $project->combination_id;
            $bookTitleInstance = CommonService::getBookTitleInstance($partCompanyId, $projectClassifyId);
            foreach ($arrChunks as $ids) {
                $serialNos = DownloadJobService::getChildSerialNos($bookTitleInstance, $ids);
                $dirName   = get_valid_path($dirName);
                $filePath  = 'public/excels/' . $dirName .'/'. $serialNos. '_卷内目录_' . date('His') . '.xlsx';
                switch ($combinationId) {
                    case 1: //29号文格式
                        (new UpFullIndexExport($projectClassifyId, $partCompanyId, $ids, $serialNos))->store($filePath);
                        break;
                    default://8号文
                        (new UpFullIndexExport($projectClassifyId, $partCompanyId, $ids, $serialNos))->store($filePath);
                        break;
                }
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
        $dirStorage  = "storage/excels/$dirName";
        $downloadUrl = (new DownloadJobService())->mergeExcel($dirStorage);
        $fileInfo    = pathinfo($downloadUrl);
        $data        = [
            'basename'     => $fileInfo['basename'],
            'download_url' => $downloadUrl
        ];
        CommonService::addActionLog('检索阶段按照单位工程导出全引目录');

        return $this->success($data);
    }

    /**
     * 借阅记录，当前登录用户的
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/2/22 11:18
     */
    public function borrowLogs(Request $request): JsonResponse
    {
        $perPage = $request->input('per_page') ?: $this->limit;
        $search  = $request->input('search');

        $list = $this->searchStageService->getBorrowLogs($perPage, $search);

        return $this->success($list);
    }

    /**
     * 借阅操作 status 0未归还,1逾期未还,2已归还
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2025-01-09 17:41
     */
    public function updateStatus(Request $request) : JsonResponse
    {
        $borrowId = $request->input('id');
        $status   = $request->input('status');
        $result   = ApprovalBorrow::query()->where('id', $borrowId)->update(['status' => $status, 'updated_at' => Carbon::now()->toTimeString()]);
        if (!$result) {
            return $this->error('操作失败！');
        }

        return $this->success('', '操作成功！');
    }


    /**
     * 获取卷内记录
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/2/22 11:20
     */
    public function getBookCatalogs(Request $request): JsonResponse
    {
        $partCompanyId     = $request->input('part_company_id');
        $projectClassifyId = $request->input('project_classify_id');
        $bookTitleId       = $request->input('book_title_id');
        $list              = $this->searchStageService->getBookCatalogs($partCompanyId, $projectClassifyId, $bookTitleId);

        return $this->success($list);
    }

    /**
     * 整个项目中检索案卷
     *
     * @author: lxk
     * @date: 2024/4/10 11:56
     */
    public function projectSearch(Request $request)
    {
        $projectId  = $request->input('project_id');
        $searchType = $request->input('search_type');
        $keyword    = $request->input('keyword');
        $perPage    = $request->input('per_page', config('site.limit'));
        $list       = (new ProjectSearchService())->projectSearch($projectId, $perPage, $searchType, $keyword);

        ProjectSearchService::saveSearchKeyword($projectId, $keyword);

        return $this->success($list);
    }

    /**
     * 获取检索记录
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/5/6 16:07
     */
    public function getHistorySearch(Request $request): JsonResponse
    {
        $projectId = $request->input('project_id');
        $list      = SearchHistory::query()->where('project_id', $projectId)->limit(20)->orderByDesc('id')->get();
        $list      = $list->isNotEmpty() ? $list->toArray() : [];

        foreach ($list as $val) {
            $val['type']   = 'info';
            $val['effect'] = 'plain';
        }

        return $this->success($list);
    }

    /**
     * 清除检索记录
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024/5/6 17:51
     */
    public function clearHistorySearch(Request $request): JsonResponse
    {
        $projectId = $request->input('project_id');
        SearchHistory::query()->where('project_id', $projectId)->delete();

        return $this->success('', '清除成功！');
    }


}
